package com.bieber.smartpost.invoke.filter.filler;

import com.bieber.smartpost.invoke.FilterContext;
import com.jbeer.framework.annotation.Bean;
import com.jbeer.framework.exception.JBeerException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 从上一个请求返回的html里面取值
 * #{html:'cssSelector&[text|val|attr:xxx]'[index][default:xxxx]}
 * Created by bieber on 14-11-30.
 */
@Bean
public class HtmlFiller extends BasicFiller<Document> {

    private static final String VALUE_TYPE_REGEX="(&\\[(text|val|attr:[\\w-]+)\\])";

    private static final String EXPRESSION_REGEX="'[\\w>\\x20\\t\\r\\n\\f#\\$\\|\\^=~\\?\\*\\.\\[\\]-]{1,}"+VALUE_TYPE_REGEX+"?'";

    private static final Pattern CSS_SELECTOR_PATTERN = Pattern.compile("#\\{html:"+EXPRESSION_REGEX+INDEX_REGEX+"?"+DEFAULT_VALUE_REGEX+"\\}");

    private static final Pattern VALUE_TYPE_PATTERN = Pattern.compile(VALUE_TYPE_REGEX);

    @Override
    protected String getExpressionRegex() {
        return EXPRESSION_REGEX;
    }

    @Override
    protected String convertValue(String originValue, Document doc) throws JBeerException {
        List<FillerRule> ruleList = generateFillerRule(CSS_SELECTOR_PATTERN,originValue);
        if(ruleList.size()<=0){
            return originValue;
        }
        String[] args = new String[ruleList.size()];
        for(int i=0;i<ruleList.size();i++){
            FillerRule rule = ruleList.get(i);
            String expression = rule.getExpression();
            Matcher matcher = VALUE_TYPE_PATTERN.matcher(expression);
            StringBuffer key = new StringBuffer();
            ValueType type = getValueType(matcher,key);
            expression = matcher.replaceAll("");
           //expression=expression.substring(1,expression.length()-1);
            Elements elements = doc.select(expression);
            if(elements.size()<=0){
                args[i]="";
            }else{
                int index=0;
                if(rule.getIndex()!=null){
                    index = rule.getIndex();
                }
                Element element = elements.get(index);
                switch (type){
                    case VAL:{
                        args[i]=element.val();
                        break;
                    }
                    case TEXT:{
                        args[i]=element.text();
                        break;
                    }
                    case ATTR:{
                        String attr = key.toString();
                        attr=attr.substring(5);
                        args[i]=element.attr(attr);
                        break;
                    }
                }
            }
        }
        originValue = CSS_SELECTOR_PATTERN.matcher(originValue).replaceAll("%s");
        return String.format(originValue,args);
    }

    @Override
    protected Document generateDataSource(FilterContext context) throws IOException, JBeerException {
        return Jsoup.parse(context.getLastResponse().getResponseContent());
    }

    private ValueType getValueType(Matcher matcher,StringBuffer key){
        if(matcher.find()){
            String valueType =  matcher.group();
            key.append(valueType.substring(2,valueType.length()-1));
            return ValueType.getType(key.toString());
        }
        return ValueType.VAL;
    }

    static enum ValueType{
        VAL("val"),TEXT("text"),ATTR("attr:[\\w-]+");
        private String value;

        ValueType(String value){
            this.value=value;
        }
        public static ValueType getType(String value){
            ValueType[] types =   ValueType.class.getEnumConstants();
            for(ValueType type:types){
                if(value.matches(type.value)){
                    return type;
                }
            }
            return null;
        }
    }
    public static void main(String[] args) throws IOException, JBeerException {

    String content = "one#{html:'#u1 > a&[text]'[0]} two#{html:'#u1 > a&[attr:href]'[1]} three#{html:'#u1 > a&[attr:href]'[2]}";
       /* Matcher matcher = CSS_SELECTOR_PATTERN.matcher(content);
        while(matcher.find()){
            System.out.println(matcher.group());
        }*/
     /*   HtmlFiller filler = new HtmlFiller();
        System.out.println(filler.generateFillerRule(CSS_SELECTOR_PATTERN, content));*/
        HtmlFiller filler = new HtmlFiller();
        URL url = new URL("http://www.baidu.com/");
        System.out.println(filler.convertValue(content,Jsoup.parse(url,10000)));
    }
}
